package com.sansan.qiangji.task;

import com.sansan.qiangji.VO.warehouse.stackerTaskIn.StackerTaskInVO;
import com.sansan.qiangji.config.RedisConfig;
import com.sansan.qiangji.entity.base.Stock;
import com.sansan.qiangji.entity.device.*;
import com.sansan.qiangji.entity.warehouse.*;
import com.sansan.qiangji.entity.warehouse.example.*;
import com.sansan.qiangji.enums.RedisLockKeyEnum;
import com.sansan.qiangji.enums.ResultEnum;
import com.sansan.qiangji.exception.ServiceException;
import com.sansan.qiangji.form.warehouse.ProductBindingStockForm;
import com.sansan.qiangji.realize.warehouse.PushOrderDetailReal;
import com.sansan.qiangji.service.impl.base.StockServiceImpl;
import com.sansan.qiangji.service.impl.device.*;
import com.sansan.qiangji.service.impl.warehouse.*;
import com.sansan.qiangji.utils.RedisLockUtil;
import com.sansan.qiangji.utils.ResultVOUtil;
import com.sansan.qiangji.utils.plcUtils.HCPlcUtil;
import com.sansan.qiangji.utils.plcUtils.TDPlcUtil;
import com.sansan.qiangji.utils.tcpUtils.YRTcpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@Component
@Slf4j
public class AsyncTask {
    private StackerServiceImpl stackerService;
    private StackerTaskInServiceImpl stackerTaskInService;
    private StackerTaskOutServiceImpl stackerTaskOutService;
    private BeltServiceImpl beltService;
    private TaskLogServiceImpl taskLogService;
    private StackerParamServiceImpl stackerParamService;
    private StackerParamDetailServiceImpl stackerParamDetailService;
    private PushOrderServiceImpl pushOrderService;
    private PushOrderDetailServiceImpl pushOrderDetailService;
    private PushOrderBoxDetailServiceImpl pushOrderBoxDetailService;
    private StockServiceImpl stockService;
    private PullOrderServiceImpl pullOrderService;
    private PullOrderDetailServiceImpl pullOrderDetailService;
    private PullOrderBoxDetailServiceImpl pullOrderBoxDetailService;
    private StackerTaskMoveServiceImpl stackerTaskMoveService;
    private MoveBoxDetailServiceImpl moveBoxDetailService;
    private BeltParamServiceImpl beltParamService;
    private BeltParamDetailServiceImpl beltParamDetailService;
    private RedisConfig redisConfig;
    private PushOrderDetailReal pushOrderDetailReal;

    @Resource
    public void setPushOrderDetailReal(PushOrderDetailReal pushOrderDetailReal) {
        this.pushOrderDetailReal = pushOrderDetailReal;
    }

    @Resource
    public void setRedisConfig(RedisConfig redisConfig) {
        this.redisConfig = redisConfig;
    }

    @Resource
    public void setStackerService(StackerServiceImpl stackerService) {
        this.stackerService = stackerService;
    }

    @Resource
    public void setStackerTaskInService(StackerTaskInServiceImpl stackerTaskInService) {
        this.stackerTaskInService = stackerTaskInService;
    }

    @Resource
    public void setStackerTaskOutService(StackerTaskOutServiceImpl stackerTaskOutService) {
        this.stackerTaskOutService = stackerTaskOutService;
    }

    @Resource
    public void setBeltService(BeltServiceImpl beltService) {
        this.beltService = beltService;
    }

    @Resource
    public void setTaskLogService(TaskLogServiceImpl taskLogService) {
        this.taskLogService = taskLogService;
    }

    @Resource
    public void setPushOrderDetailService(PushOrderDetailServiceImpl pushOrderDetailService) {
        this.pushOrderDetailService = pushOrderDetailService;
    }

    @Resource
    public void setPushOrderBoxDetailService(PushOrderBoxDetailServiceImpl pushOrderBoxDetailService) {
        this.pushOrderBoxDetailService = pushOrderBoxDetailService;
    }

    @Resource
    public void setPushOrderService(PushOrderServiceImpl pushOrderService) {
        this.pushOrderService = pushOrderService;
    }

    @Resource
    public void setStackerParamService(StackerParamServiceImpl stackerParamService) {
        this.stackerParamService = stackerParamService;
    }

    @Resource
    public void setStackerParamDetailService(StackerParamDetailServiceImpl stackerParamDetailService) {
        this.stackerParamDetailService = stackerParamDetailService;
    }

    @Resource
    public void setStockService(StockServiceImpl stockService) {
        this.stockService = stockService;
    }

    @Resource
    public void setPullOrderService(PullOrderServiceImpl pullOrderService) {
        this.pullOrderService = pullOrderService;
    }

    @Resource
    public void setPullOrderDetailService(PullOrderDetailServiceImpl pullOrderDetailService) {
        this.pullOrderDetailService = pullOrderDetailService;
    }

    @Resource
    public void setPullOrderBoxDetailService(PullOrderBoxDetailServiceImpl pullOrderBoxDetailService) {
        this.pullOrderBoxDetailService = pullOrderBoxDetailService;
    }

    @Resource
    public void setStackerTaskMoveService(StackerTaskMoveServiceImpl stackerTaskMoveService) {
        this.stackerTaskMoveService = stackerTaskMoveService;
    }

    @Resource
    public void setMoveBoxDetailService(MoveBoxDetailServiceImpl moveBoxDetailService) {
        this.moveBoxDetailService = moveBoxDetailService;
    }

    @Resource
    public void setBeltParamService(BeltParamServiceImpl beltParamService) {
        this.beltParamService = beltParamService;
    }

    @Resource
    public void setBeltParamDetailService(BeltParamDetailServiceImpl beltParamDetailService) {
        this.beltParamDetailService = beltParamDetailService;
    }

    @Async
    public Future<Boolean> receiveScanCode(Scan scan) {
        YRTcpUtil yrTcpUtil = new YRTcpUtil(scan.getScanIp(), scan.getScanPort());
        if (yrTcpUtil.checkScanVer() != null) {
            log.info("扫码枪在线IP={}", scan.getScanIp());
            yrTcpUtil.openScan();
            String code = yrTcpUtil.receiveScanData(3000);
            yrTcpUtil.disConnect();
            if (code != null && code.substring(0, 4).equals("6688")) {
                Jedis jedis = new Jedis(redisConfig.getHost(), redisConfig.getPort());
                String requestId = UUID.randomUUID().toString();
                if (!redisConfig.getPassword().equals("")) {
                    jedis.auth(redisConfig.getPassword());
                }
                try {
                    for (int i = 0; i < 5; i++) {
                        if (!RedisLockUtil.tryGetDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId, 5000)) {
                            if (i == 4) {
                                log.error("【任务执行】系统任务繁忙 !");
                                throw new ServiceException(ResultEnum.STACKER_TASK_BUSY);
                            }
                            try {
                                Thread.sleep(1000);
                            } catch (Exception ignored) {
                            }
                            continue;
                        }
                        ProductBindingStockForm productBindingStockForm = new ProductBindingStockForm();
                        productBindingStockForm.setBoxCode(code);
                        productBindingStockForm.setShelveName(scan.getShelveName());
                        pushOrderDetailReal.productBindingStock(productBindingStockForm);
                        break;
                    }
                    jedis.close();
                    RedisLockUtil.releaseDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId);
                } catch (Exception e) {
                    jedis.close();
                    RedisLockUtil.releaseDistributedLock(jedis, RedisLockKeyEnum.STACKER_TASK_LOCK.getKey(), requestId);
                    throw e;
                }
            }
        }
        return new AsyncResult<>(true);
    }

    @Async
    public Future<Boolean> writeStackerParamDetail(Stacker stacker) {
        TDPlcUtil tdPlcUtil = new TDPlcUtil(stacker.getStackerIP(), stacker.getStackerPort());
        try {
            Boolean connectResult = tdPlcUtil.isConnect();
            List<StackerParamDetail> stackerParamDetailsUpdate = new ArrayList<>();
            if (connectResult) {
                List<StackerParamDetail> stackerParamDetails = stackerParamDetailService.findByStackerName(stacker.getStackerName());
                for (StackerParamDetail stackerParamDetail : stackerParamDetails) {
                    if (stackerParamDetail.getStackerParamChangeValue() != null) {
                        Long changeValue = stackerParamDetail.getStackerParamChangeValue();
                        stackerParamDetail.setStackerParamValue(null);
                        if (stackerParamDetail.getStackerParamType().equals("Word")) {
                            try {
                                int address = Integer.parseInt(stackerParamDetail.getStackerParamAddress());
                                tdPlcUtil.writeStorageWord(address, new int[]{changeValue.intValue()});
                                Integer[] results = tdPlcUtil.readStorageWord(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParamDetail.getStackerParamType().equals("DWord")) {
                            try {
                                int address = Integer.parseInt(stackerParamDetail.getStackerParamAddress());
                                tdPlcUtil.writeStorageDWord(address, new long[]{changeValue});
                                Long[] results = tdPlcUtil.readStorageDWord(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0]);
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParamDetail.getStackerParamType().equals("Int")) {
                            try {
                                int address = Integer.parseInt(stackerParamDetail.getStackerParamAddress());
                                tdPlcUtil.writeStorageInt(address, new short[]{changeValue.shortValue()});
                                Short[] results = tdPlcUtil.readStorageInt(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParamDetail.getStackerParamType().equals("DInt")) {
                            try {
                                int address = Integer.parseInt(stackerParamDetail.getStackerParamAddress());
                                tdPlcUtil.writeStorageDInt(address, new int[]{changeValue.intValue()});
                                Integer[] results = tdPlcUtil.readStorageDInt(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParamDetail.getStackerParamType().equals("QX")) {
                            try {
                                Double.parseDouble(stackerParamDetail.getStackerParamAddress());
                                if (stackerParamDetail.getStackerParamAddress().length() - stackerParamDetail.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    if (changeValue == 0) {
                                        tdPlcUtil.writeBitQX(stackerParamDetail.getStackerParamAddress(), new Boolean[]{false});
                                    }
                                    if (changeValue == 1) {
                                        tdPlcUtil.writeBitQX(stackerParamDetail.getStackerParamAddress(), new Boolean[]{true});
                                    }
                                    Boolean[] results = tdPlcUtil.readBitQX(stackerParamDetail.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetail.setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetail.setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParamDetail.getStackerParamType().equals("MX")) {
                            try {
                                Double.parseDouble(stackerParamDetail.getStackerParamAddress());
                                if (stackerParamDetail.getStackerParamAddress().length() - stackerParamDetail.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    if (changeValue == 0) {
                                        tdPlcUtil.writeBitMX(stackerParamDetail.getStackerParamAddress(), new Boolean[]{false});
                                    }
                                    if (changeValue == 1) {
                                        tdPlcUtil.writeBitMX(stackerParamDetail.getStackerParamAddress(), new Boolean[]{true});
                                    }
                                    Boolean[] results = tdPlcUtil.readBitMX(stackerParamDetail.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetail.setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetail.setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        stackerParamDetail.setStackerParamChangeValue(null);
                        stackerParamDetailsUpdate.add(stackerParamDetail);
                    }
                }
                if (stackerParamDetailsUpdate.size() != 0) {
                    stackerParamDetailService.updateStackerParamDetailsChangeValue(stackerParamDetailsUpdate);
                }
            }
            tdPlcUtil.disConnect();
        } catch (Exception e) {
            log.error("【堆垛机参数写入轮询】堆垛机参数写入轮询发生异常，stacker={}", stacker.toString());
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            tdPlcUtil.disConnect();
        }
        return new AsyncResult<>(true);
    }

    @Async
    public Future<Boolean> writeBeltParamDetail(Belt belt) {
        HCPlcUtil hcPlcUtil = new HCPlcUtil(belt.getBeltIp(), belt.getBeltPort());
        try {
            Boolean connectResult = hcPlcUtil.isConnect();
            List<BeltParamDetail> beltParamDetailsUpdate = new ArrayList<>();
            if (connectResult) {
                List<BeltParamDetail> beltParamDetails = beltParamDetailService.findByBeltName(belt.getBeltName());
                for (BeltParamDetail beltParamDetail : beltParamDetails) {
                    if (beltParamDetail.getBeltParamChangeValue() != null) {
                        Long changeValue = beltParamDetail.getBeltParamChangeValue();
                        beltParamDetail.setBeltParamValue(null);
                        if (beltParamDetail.getBeltParamType().equals("M")) {
                            try {
                                int address = Integer.parseInt(beltParamDetail.getBeltParamAddress());
                                if (changeValue == 0) {
                                    hcPlcUtil.writeCoil(address, new Boolean[]{false});
                                }
                                if (changeValue == 1) {
                                    hcPlcUtil.writeCoil(address, new Boolean[]{true});
                                }
                                Boolean[] results = hcPlcUtil.readCoil(address, 1);
                                if (results != null && results.length == 1) {
                                    beltParamDetail.setBeltParamValue(0L);
                                    if (results[0]) {
                                        beltParamDetail.setBeltParamValue(1L);
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (beltParamDetail.getBeltParamType().equals("D")) {
                            try {
                                int address = Integer.parseInt(beltParamDetail.getBeltParamAddress());
                                hcPlcUtil.writeStorage(address, new int[]{changeValue.intValue()});
                                Integer[] results = hcPlcUtil.readStorage(address, 1);
                                if (results != null && results.length == 1) {
                                    beltParamDetail.setBeltParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        beltParamDetail.setBeltParamChangeValue(null);
                        beltParamDetailsUpdate.add(beltParamDetail);
                    }
                }
                if (beltParamDetailsUpdate.size() != 0) {
                    beltParamDetailService.updateBeltParamDetailsChangeValue(beltParamDetailsUpdate);
                }
            }
            hcPlcUtil.disConnect();
        } catch (Exception e) {
            log.error("【堆垛机参数写入轮询】堆垛机参数写入轮询发生异常，belt={}", belt.toString());
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            hcPlcUtil.disConnect();
        }
        return new AsyncResult<>(true);
    }

    @Async
    public Future<Boolean> checkStackerStatus(Stacker stacker) {
        TDPlcUtil tdPlcUtil = new TDPlcUtil(stacker.getStackerIP(), stacker.getStackerPort());
        try {
            Boolean connectResult = tdPlcUtil.isConnect();
            boolean isUpdate = false;
            if (connectResult) {
                log.info("【堆垛机通信】堆垛机在线，IP={}", stacker.getStackerIP());
            }
            if ((connectResult && !stacker.getStackerOnlineStatus()) || (!connectResult && stacker.getStackerOnlineStatus())) {
                stacker.setStackerOnlineStatus(!stacker.getStackerOnlineStatus());
                isUpdate = true;
            }
            if (connectResult && stacker.getIsRefreshStackerParam()) {
                stacker.setIsRefreshStackerParam(false);
                List<StackerParam> stackerParams = stackerParamService.findAll();
                List<StackerParamDetail> stackerParamDetails = stackerParamDetailService.findByStackerName(stacker.getStackerName());
                List<StackerParamDetail> stackerParamDetailsAdd = new ArrayList<>();
                List<StackerParamDetail> stackerParamDetailsDelete = new ArrayList<>();
                List<StackerParamDetail> stackerParamDetailsUpdate = new ArrayList<>();
                for (StackerParam stackerParam : stackerParams) {
                    List<StackerParamDetail> stackerParamDetailList = stackerParamDetails.stream().filter(e -> e.getStackerParamName().equals(stackerParam.getStackerParamName())).collect(Collectors.toList());
                    if (stackerParamDetailList.size() != 0) {
                        BeanUtils.copyProperties(stackerParam, stackerParamDetailList.get(0));
                        stackerParamDetailList.get(0).setStackerParamChangeValue(null);
                        if (stackerParam.getStackerParamType().equals("Word")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Integer[] results = tdPlcUtil.readStorageWord(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetailList.get(0).setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("DWord")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Long[] results = tdPlcUtil.readStorageDWord(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetailList.get(0).setStackerParamValue(results[0]);
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("Int")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Short[] results = tdPlcUtil.readStorageInt(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetailList.get(0).setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("DInt")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Integer[] results = tdPlcUtil.readStorageDInt(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetailList.get(0).setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("IX")) {
                            try {
                                Double.parseDouble(stackerParam.getStackerParamAddress());
                                if (stackerParam.getStackerParamAddress().length() - stackerParam.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    Boolean[] results = tdPlcUtil.readBitIX(stackerParam.getStackerParamAddress(), 2);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetailList.get(0).setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetailList.get(0).setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("QX")) {
                            try {
                                Double.parseDouble(stackerParam.getStackerParamAddress());
                                if (stackerParam.getStackerParamAddress().length() - stackerParam.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    Boolean[] results = tdPlcUtil.readBitQX(stackerParam.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetailList.get(0).setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetailList.get(0).setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("MX")) {
                            try {
                                Double.parseDouble(stackerParam.getStackerParamAddress());
                                if (stackerParam.getStackerParamAddress().length() - stackerParam.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    Boolean[] results = tdPlcUtil.readBitMX(stackerParam.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetailList.get(0).setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetailList.get(0).setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        stackerParamDetailsUpdate.add(stackerParamDetailList.get(0));
                    } else {
                        StackerParamDetail stackerParamDetail = new StackerParamDetail();
                        BeanUtils.copyProperties(stackerParam, stackerParamDetail);
                        stackerParamDetail.setStackerName(stacker.getStackerName());
                        if (stackerParam.getStackerParamType().equals("Word")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Integer[] results = tdPlcUtil.readStorageWord(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("DWord")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Long[] results = tdPlcUtil.readStorageDWord(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0]);
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("Int")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Short[] results = tdPlcUtil.readStorageInt(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("DInt")) {
                            try {
                                int address = Integer.parseInt(stackerParam.getStackerParamAddress());
                                Integer[] results = tdPlcUtil.readStorageDInt(address, 1);
                                if (results != null && results.length == 1) {
                                    stackerParamDetail.setStackerParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("IX")) {
                            try {
                                Double.parseDouble(stackerParam.getStackerParamAddress());
                                if (stackerParam.getStackerParamAddress().length() - stackerParam.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    Boolean[] results = tdPlcUtil.readBitIX(stackerParam.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetail.setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetail.setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("QX")) {
                            try {
                                Double.parseDouble(stackerParam.getStackerParamAddress());
                                if (stackerParam.getStackerParamAddress().length() - stackerParam.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    Boolean[] results = tdPlcUtil.readBitQX(stackerParam.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetail.setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetail.setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (stackerParam.getStackerParamType().equals("MX")) {
                            try {
                                Double.parseDouble(stackerParam.getStackerParamAddress());
                                if (stackerParam.getStackerParamAddress().length() - stackerParam.getStackerParamAddress().indexOf(".") - 1 == 1) {
                                    Boolean[] results = tdPlcUtil.readBitQX(stackerParam.getStackerParamAddress(), 1);
                                    if (results != null && results.length == 1) {
                                        stackerParamDetail.setStackerParamValue(0L);
                                        if (results[0]) {
                                            stackerParamDetail.setStackerParamValue(1L);
                                        }
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        stackerParamDetailsAdd.add(stackerParamDetail);
                    }
                }
                for (StackerParamDetail stackerParamDetail : stackerParamDetails) {
                    if (stackerParams.stream().noneMatch(e -> e.getStackerParamName().equals(stackerParamDetail.getStackerParamName()))) {
                        stackerParamDetailsDelete.add(stackerParamDetail);
                    }
                }
                if (stackerParamDetailsAdd.size() != 0) {
                    stackerParamDetailService.insertStackerParamDetails(stackerParamDetailsAdd);
                }
                if (stackerParamDetailsDelete.size() != 0) {
                    stackerParamDetailService.deleteStackerParamDetails(stackerParamDetailsDelete);
                }
                if (stackerParamDetailsUpdate.size() != 0) {
                    stackerParamDetailService.updateStackerParamNotChangeValueDetails(stackerParamDetailsUpdate);
                }
                isUpdate = true;
            }
            if (isUpdate) {
                stackerService.updateStacker(stacker);
            }
            tdPlcUtil.disConnect();
        } catch (Exception e) {
            log.error("【堆垛机轮询】堆垛机轮询发生异常，stacker={}", stacker.toString());
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            tdPlcUtil.disConnect();
        }
        return new AsyncResult<>(true);
    }

    @Async
    public Future<Boolean> checkBeltStatus(Belt belt) {
        HCPlcUtil hcPlcUtil = new HCPlcUtil(belt.getBeltIp(), belt.getBeltPort());
        try {
            Boolean connectResult = hcPlcUtil.isConnect();
            boolean isUpdate = false;
            if (connectResult) {
                log.info("【传送带通信】传送带在线，IP={}", belt.getBeltIp());
            }
            if ((connectResult && !belt.getBeltOnlineStatus()) || (!connectResult && belt.getBeltOnlineStatus())) {
                belt.setBeltOnlineStatus(!belt.getBeltOnlineStatus());
                isUpdate = true;
            }
            if (connectResult && belt.getIsRefreshBeltParam()) {
                belt.setIsRefreshBeltParam(false);
                List<BeltParam> beltParams = beltParamService.findAll();
                List<BeltParamDetail> beltParamDetails = beltParamDetailService.findByBeltName(belt.getBeltName());
                List<BeltParamDetail> beltParamDetailsAdd = new ArrayList<>();
                List<BeltParamDetail> beltParamDetailsDelete = new ArrayList<>();
                List<BeltParamDetail> beltParamDetailsUpdate = new ArrayList<>();
                for (BeltParam beltParam : beltParams) {
                    List<BeltParamDetail> beltParamDetailList = beltParamDetails.stream().filter(e -> e.getBeltParamName().equals(beltParam.getBeltParamName())).collect(Collectors.toList());
                    if (beltParamDetailList.size() != 0) {
                        BeanUtils.copyProperties(beltParam, beltParamDetailList.get(0));
                        beltParamDetailList.get(0).setBeltParamChangeValue(null);
                        if (beltParam.getBeltParamType().equals("M")) {
                            try {
                                int address = Integer.parseInt(beltParam.getBeltParamAddress());
                                Boolean[] results = hcPlcUtil.readCoil(address, 1);
                                if (results != null && results.length == 1) {
                                    beltParamDetailList.get(0).setBeltParamValue(0L);
                                    if (results[0]) {
                                        beltParamDetailList.get(0).setBeltParamValue(1L);
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (beltParam.getBeltParamType().equals("D")) {
                            try {
                                int address = Integer.parseInt(beltParam.getBeltParamAddress());
                                Integer[] results = hcPlcUtil.readStorage(address, 1);
                                if (results != null && results.length == 1) {
                                    beltParamDetailList.get(0).setBeltParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        beltParamDetailsUpdate.add(beltParamDetailList.get(0));
                    } else {
                        BeltParamDetail beltParamDetail = new BeltParamDetail();
                        BeanUtils.copyProperties(beltParam, beltParamDetail);
                        beltParamDetail.setBeltName(belt.getBeltName());
                        if (beltParam.getBeltParamType().equals("M")) {
                            try {
                                int address = Integer.parseInt(beltParam.getBeltParamAddress());
                                Boolean[] results = hcPlcUtil.readCoil(address, 1);
                                if (results != null && results.length == 1) {
                                    beltParamDetail.setBeltParamValue(0L);
                                    if (results[0]) {
                                        beltParamDetail.setBeltParamValue(1L);
                                    }
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        if (beltParam.getBeltParamType().equals("D")) {
                            try {
                                int address = Integer.parseInt(beltParam.getBeltParamAddress());
                                Integer[] results = hcPlcUtil.readStorage(address, 1);
                                if (results != null && results.length == 1) {
                                    beltParamDetail.setBeltParamValue(results[0].longValue());
                                }
                            } catch (Exception ignored) {
                            }
                        }
                        beltParamDetailsAdd.add(beltParamDetail);
                    }
                }
                for (BeltParamDetail beltParamDetail : beltParamDetails) {
                    if (beltParams.stream().noneMatch(e -> e.getBeltParamName().equals(beltParamDetail.getBeltParamName()))) {
                        beltParamDetailsDelete.add(beltParamDetail);
                    }
                }
                if (beltParamDetailsAdd.size() != 0) {
                    beltParamDetailService.insertBeltParamDetails(beltParamDetailsAdd);
                }
                if (beltParamDetailsDelete.size() != 0) {
                    beltParamDetailService.deleteBeltParamDetails(beltParamDetailsDelete);
                }
                if (beltParamDetailsUpdate.size() != 0) {
                    beltParamDetailService.updateBeltParamNotChangeValueDetails(beltParamDetailsUpdate);
                }
                isUpdate = true;
            }
            if (isUpdate) {
                beltService.updateBelt(belt);
            }
            hcPlcUtil.disConnect();
        } catch (Exception e) {
            log.error("【传送带轮询】传送带轮询发生异常，belt={}", belt.toString());
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            hcPlcUtil.disConnect();
        }
        return new AsyncResult<>(true);
    }

    @Async
    public void pushProduct(String stackerTaskInCode) {
        TDPlcUtil tdPlcUtil = null;
        HCPlcUtil hcPlcUtil = null;
        try {
            log.info("【入库任务】stackerTaskCode={}", stackerTaskInCode);
            StackerTaskIn stackerTaskIn = stackerTaskInService.findByStackerTaskInCode(stackerTaskInCode);
            List<Stacker> stackers = new ArrayList<>();
            List<Belt> belts = new ArrayList<>();
            List<PushOrder> pushOrders = new ArrayList<>();
            List<PushOrderDetail> pushOrderDetails = new ArrayList<>();
            List<PushOrderBoxDetail> pushOrderBoxDetails = new ArrayList<>();
            List<Stock> stocks = new ArrayList<>();
            if (stackerTaskIn != null) {
                if (stackerTaskIn.getStackerName() != null) {
                    stackers = stackerService.findByStackerName(stackerTaskIn.getStackerName());
                }
                if (stackers.size() != 0) {
                    belts = beltService.findByStackerName(stackers.get(0).getStackerName());
                }
                if (stackerTaskIn.getPushOrderCode() != null) {
                    PushOrderExample pushOrderExample = new PushOrderExample();
                    pushOrderExample.or().andPushOrderCodeEqualTo(stackerTaskIn.getPushOrderCode());
                    pushOrders = pushOrderService.selectByExample(pushOrderExample);
                }
                if (stackerTaskIn.getPushOrderDetailCode() != null) {
                    PushOrderDetailExample pushOrderDetailExample = new PushOrderDetailExample();
                    pushOrderDetailExample.or().andPushOrderDetailCodeEqualTo(stackerTaskIn.getPushOrderDetailCode());
                    pushOrderDetails = pushOrderDetailService.selectByExample(pushOrderDetailExample);
                }
                if (stackerTaskIn.getPushOrderBoxDetailCode() != null) {
                    pushOrderBoxDetails = pushOrderBoxDetailService.findByBoxDetailCode(stackerTaskIn.getPushOrderBoxDetailCode());
                }
                if (stackerTaskIn.getShelveName() != null && stackerTaskIn.getStockWidth() != null && stackerTaskIn.getStockHeight() != null) {
                    stocks = stockService.findByShelveNameAndWidthAndHeight(stackerTaskIn.getShelveName(), stackerTaskIn.getStockWidth(), stackerTaskIn.getStockHeight());
                }
            }
            for (int i = 0; i < 1; i++) {
                if (stackerTaskIn == null) {
                    log.error("【入库任务】堆垛机任务不存在，stackerTaskInCode={}", stackerTaskInCode);
                    break;
                }
                taskLogService.deleteByStackerName(stackerTaskIn.getStackerName());
                if (stackers.size() == 0) {
                    log.error("【入库任务】堆垛机不存在，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "堆垛机不存在");
                    break;
                }
                if (belts.size() == 0) {
                    log.error("【入库任务】传送带不存在，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "传送带不存在");
                    break;
                }
                if (pushOrders.size() == 0) {
                    log.error("【入库任务】入库单不存在，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "入库单不存在");
                    break;
                }
                if (pushOrderDetails.size() == 0) {
                    log.error("【入库任务】入库详情不存在，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "入库详情不存在");
                    break;
                }
                if (pushOrderBoxDetails.size() == 0) {
                    log.error("【入库任务】入库货物箱子详情不存在，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "入库货物箱子详情不存在");
                    break;
                }
                if (stocks.size() == 0 || !stocks.get(0).getStockStatus().equals("已绑定")) {
                    log.error("【入库任务】货位不存在或未绑定，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "货位不存在或未绑定");
                    break;
                }
                if (stackers.get(0).getStackerIP() == null || stackers.get(0).getStackerIP().equals("")
                        || stackers.get(0).getStackerPort() == null
                        || stackers.get(0).getStackerPickAddress() == null
                        || stackers.get(0).getStackerPickHeight() == null
                        || stackers.get(0).getStackerPickWidth() == null) {
                    log.error("【入库任务】堆垛机参数缺失，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "堆垛机参数缺失");
                    break;
                }
                if (stackerTaskIn.getStockWidth() == null || stackerTaskIn.getStockHeight() == null
                        || stackerTaskIn.getShelvePlcValue() == null) {
                    log.error("【入库任务】任务参数缺失，stackerTaskInCode={}", stackerTaskInCode);
                    taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "任务参数缺失");
                    break;
                }
                taskLogService.log(stackerTaskInCode, stackerTaskIn.getStackerName(), "入库中");
                tdPlcUtil = new TDPlcUtil(stackers.get(0).getStackerIP(), stackers.get(0).getStackerPort());
                hcPlcUtil = new HCPlcUtil(belts.get(0).getBeltIp(), belts.get(0).getBeltPort());
                if (!stackerTaskIn.getStackerTaskInPace().equals("到位") && !stackerTaskIn.getStackerTaskInPace().equals("取货") && !stackerTaskIn.getStackerTaskInPace().equals("放货")) {
                    if (!beltGetProduct(stackerTaskIn, stackers.get(0), tdPlcUtil, hcPlcUtil)) {
                        log.error("【入库任务】传送带取货失败，stackerTaskInCode={}", stackerTaskInCode);
                        break;
                    }
                    // 模拟到位过程
                    /*try {
                        Thread.sleep(10000);
                    } catch (Exception ignored) {
                    }
                    int max = 100, min = 1;
                    int ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【入库任务】堆垛机取货失败，stackerTaskInCode={}", stackerTaskInCode);
                        break;
                    }*/
                    stackerTaskIn.setStackerTaskInPace("到位");
                    stackerTaskInService.updateStackerTaskIn(stackerTaskIn);
                }
                if (!stackerTaskIn.getStackerTaskInPace().equals("取货") && !stackerTaskIn.getStackerTaskInPace().equals("放货")) {
                    if (!pushGetProduct(stackerTaskIn, stackers.get(0), tdPlcUtil)) {
                        log.error("【入库任务】堆垛机取货失败，stackerTaskInCode={}", stackerTaskInCode);
                        break;
                    }
                    // 模拟取货过程
                    /*try {
                        Thread.sleep(10000);
                    } catch (Exception ignored) {
                    }
                    int max = 100, min = 1;
                    int ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【入库任务】堆垛机取货失败，stackerTaskInCode={}", stackerTaskInCode);
                        break;
                    }*/
                    stackerTaskIn.setStackerTaskInPace("取货");
                    stackerTaskInService.updateStackerTaskIn(stackerTaskIn);
                }
                log.info("【入库任务】堆垛机取货成功");
                if (!stackerTaskIn.getStackerTaskInPace().equals("放货")) {
                    if (!pushDownProduct(stackerTaskIn, tdPlcUtil, hcPlcUtil)) {
                        log.error("【入库任务】堆垛机放货失败，stackerTaskInCode={}", stackerTaskInCode);
                        break;
                    }
                    // 模拟放货过程
                    /*try {
                        Thread.sleep(10000);
                    } catch (Exception ignored) {
                    }
                    int max = 100, min = 1;
                    int ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【入库任务】堆垛机放货失败，stackerTaskInCode={}", stackerTaskInCode);
                        break;
                    }*/
                }
                log.info("【入库任务】堆垛机放货成功");
                /*Boolean stockPositionStatus = checkStockPosition(stackers.get(0), stackerTaskIn.getShelvePlcValue(), stackerTaskIn.getStockWidth(), stackerTaskIn.getStockHeight(), stackerTaskIn.getStackerTaskInCode());
                if (stockPositionStatus == null || !stockPositionStatus) {
                    log.error("【入库任务】判断货位状态失败，stackerTaskInCode={}", stackerTaskInCode);
                    break;
                }*/
                // 模拟判断货位状态
                /*try {
                    Thread.sleep(10000);
                } catch (Exception ignored) {
                }
                int max = 100, min = 1;
                int ran2 = (int) (Math.random() * (max - min) + min);
                if (ran2 > 80) {
                    log.error("【入库任务】判断货位状态失败，stackerTaskInCode={}", stackerTaskInCode);
                    break;
                }*/
                log.info("【入库任务】判断货位状态成功");
                pushOrderBoxDetails.get(0).setBoxDetailStatus("已入库");
                pushOrderBoxDetailService.updateByPrimaryKey(pushOrderBoxDetails.get(0));
                List<PushOrderBoxDetail> pushOrderBoxDetailList = pushOrderBoxDetailService.findByDetailCodeAndStatus(pushOrderBoxDetails.get(0).getPushOrderDetailCode(), "已入库");
                Integer countSum = pushOrderBoxDetailList.stream().mapToInt(PushOrderBoxDetail::getUnintCount).sum();
                pushOrderDetails.get(0).setFinishCount(countSum);
                if (pushOrderDetails.get(0).getPushOrderCount() != 0) {
                    if (pushOrderDetails.get(0).getFinishCount() >= pushOrderDetails.get(0).getPushOrderCount()) {
                        pushOrderDetails.get(0).setProductPushPace("已完成");
                    }
                }
                if (pushOrderDetails.get(0).getPushOrderCount() == 0) {
                    List<PushOrderBoxDetail> pushOrderBoxDetails1 = pushOrderBoxDetailList.stream().filter(e -> !e.getBoxDetailStatus().equals("已入库")).collect(Collectors.toList());
                    if (pushOrderBoxDetails1.size() == 0) {
                        pushOrderDetails.get(0).setProductPushPace("已完成");
                    }
                }
                pushOrderDetailService.updateByPrimaryKey(pushOrderDetails.get(0));
                PushOrderDetailExample pushOrderDetailExample = new PushOrderDetailExample();
                pushOrderDetailExample.or().andPushOrderCodeEqualTo(pushOrderDetails.get(0).getPushOrderCode());
                List<PushOrderDetail> pushOrderDetailList = pushOrderDetailService.selectByExample(pushOrderDetailExample);
                pushOrderDetailList = pushOrderDetailList.stream().filter(e -> e.getProductPushPace() != null && e.getProductPushPace().equals("进行中")).collect(Collectors.toList());
                pushOrders.get(0).setPushOrderStatus("入库中");
                if (pushOrderDetailList.size() == 0) {
                    pushOrders.get(0).setPushOrderStatus("已完成");
                }
                pushOrderService.updateByPrimaryKey(pushOrders.get(0));
                stocks.get(0).setPushTime(new Date());
                stocks.get(0).setStockStatus("已存放");
                stockService.updateByPrimaryKey(stocks.get(0));
                stackerTaskIn.setStackerTaskInPace("放货");
                stackerTaskIn.setStackerTaskInStatus("已完成");
                stackerTaskInService.updateStackerTaskIn(stackerTaskIn);
            }
            if (stackerTaskIn != null && !stackerTaskIn.getStackerTaskInStatus().equals("已完成")) {
                stackerTaskIn.setStackerTaskInStatus("中断");
                stackerTaskInService.updateStackerTaskIn(stackerTaskIn);
            }
            if (tdPlcUtil != null) {
                tdPlcUtil.disConnect();
            }
            if (hcPlcUtil != null) {
                hcPlcUtil.disConnect();
            }
        } catch (Exception e) {
            log.error("【入库任务】任务发生异常，stackerTaskCode={}", stackerTaskInCode);
            if (tdPlcUtil != null) {
                tdPlcUtil.disConnect();
            }
            if (hcPlcUtil != null) {
                hcPlcUtil.disConnect();
            }
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            StackerTaskIn stackerTaskIn = stackerTaskInService.findByStackerTaskInCode(stackerTaskInCode);
            if (stackerTaskIn != null) {
                stackerTaskIn.setStackerTaskInStatus("中断");
                stackerTaskInService.updateStackerTaskIn(stackerTaskIn);
            }
        }
    }

    @Async
    public void pullProduct(String stackerTaskOutCode) {
        TDPlcUtil tdPlcUtil = null;
        HCPlcUtil hcPlcUtil = null;
        try {
            log.info("【出库任务】stackerTaskOutCode={}", stackerTaskOutCode);
            StackerTaskOut stackerTaskOut = stackerTaskOutService.findByStackerTaskOutCode(stackerTaskOutCode);
            List<Stacker> stackers = new ArrayList<>();
            List<Belt> belts = new ArrayList<>();
            List<PullOrder> pullOrders = new ArrayList<>();
            List<PullOrderDetail> pullOrderDetails = new ArrayList<>();
            List<PullOrderBoxDetail> pullOrderBoxDetails = new ArrayList<>();
            List<Stock> stocks = new ArrayList<>();
            if (stackerTaskOut != null) {
                if (stackerTaskOut.getStackerName() != null) {
                    stackers = stackerService.findByStackerName(stackerTaskOut.getStackerName());
                }
                if (stackers.size() != 0) {
                    belts = beltService.findByStackerName(stackers.get(0).getStackerName());
                }
                if (stackerTaskOut.getPullOrderCode() != null) {
                    PullOrderExample pullOrderExample = new PullOrderExample();
                    pullOrderExample.or().andPullOrderCodeEqualTo(stackerTaskOut.getPullOrderCode());
                    pullOrders = pullOrderService.selectByExample(pullOrderExample);
                }
                if (stackerTaskOut.getPullOrderDetailCode() != null) {
                    PullOrderDetailExample pullOrderDetailExample = new PullOrderDetailExample();
                    pullOrderDetailExample.or().andPullOrderDetailCodeEqualTo(stackerTaskOut.getPullOrderDetailCode());
                    pullOrderDetails = pullOrderDetailService.selectByExample(pullOrderDetailExample);
                }
                if (stackerTaskOut.getPullOrderBoxDetailCode() != null) {
                    pullOrderBoxDetails = pullOrderBoxDetailService.findByBoxDetailCode(stackerTaskOut.getPullOrderBoxDetailCode());
                }
                if (stackerTaskOut.getShelveName() != null && stackerTaskOut.getStockWidth() != null && stackerTaskOut.getStockHeight() != null) {
                    stocks = stockService.findByShelveNameAndWidthAndHeight(stackerTaskOut.getShelveName(), stackerTaskOut.getStockWidth(), stackerTaskOut.getStockHeight());
                }
            }
            for (int i = 0; i < 1; i++) {
                if (stackerTaskOut == null) {
                    log.error("【出库任务】堆垛机任务不存在，stackerTaskOutCode={}", stackerTaskOutCode);
                    break;
                }
                taskLogService.deleteByStackerName(stackerTaskOut.getStackerName());
                if (stackers.size() == 0) {
                    log.error("【出库任务】堆垛机不存在，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "堆垛机不存在");
                    break;
                }
                if (belts.size() == 0) {
                    log.error("【出库任务】传送带不存在，stackerTaskInCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "传送带不存在");
                    break;
                }
                if (pullOrders.size() == 0) {
                    log.error("【出库任务】出库单不存在，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "出库单不存在");
                    break;
                }
                if (pullOrderDetails.size() == 0) {
                    log.error("【出库任务】出库详情不存在，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "出库详情不存在");
                    break;
                }
                if (pullOrderBoxDetails.size() == 0) {
                    log.error("【出库任务】入库货物箱子详情不存在，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "入库货物箱子详情不存在");
                    break;
                }
                if (stocks.size() == 0 || !stocks.get(0).getStockStatus().equals("已绑定")) {
                    log.error("【出库任务】货位不存在或未绑定，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "货位不存在或未绑定");
                    break;
                }
                if (stackers.get(0).getStackerIP() == null || stackers.get(0).getStackerIP().equals("")
                        || stackers.get(0).getStackerPort() == null
                        || stackers.get(0).getStackerPickAddress() == null
                        || stackers.get(0).getStackerPickHeight() == null
                        || stackers.get(0).getStackerPickWidth() == null) {
                    log.error("【出库任务】堆垛机参数缺失，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "堆垛机参数缺失");
                    break;
                }
                if (stackerTaskOut.getStockWidth() == null || stackerTaskOut.getStockHeight() == null
                        || stackerTaskOut.getShelvePlcValue() == null) {
                    log.error("【出库任务】任务参数缺失，stackerTaskOutCode={}", stackerTaskOutCode);
                    taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "任务参数缺失");
                    break;
                }
                taskLogService.log(stackerTaskOutCode, stackerTaskOut.getStackerName(), "出库中");
                tdPlcUtil = new TDPlcUtil(stackers.get(0).getStackerIP(), stackers.get(0).getStackerPort());
                hcPlcUtil = new HCPlcUtil(belts.get(0).getBeltIp(), belts.get(0).getBeltPort());
                if (!stackerTaskOut.getStackerTaskOutPace().equals("取货") && !stackerTaskOut.getStackerTaskOutPace().equals("放货")) {
                    if (!pullGetProduct(stackerTaskOut, stackers.get(0), tdPlcUtil)) {
                        log.error("【出库任务】堆垛机取货失败，stackerTaskOutCode={}", stackerTaskOutCode);
                        break;
                    }
                    // 模拟取货过程
                    /*try {
                        Thread.sleep(10000);
                    } catch (Exception ignored) {
                    }
                    int max = 100, min = 1;
                    int ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【出库任务】堆垛机取货失败，stackerTaskOutCode={}", stackerTaskOutCode);
                        break;
                    }*/
                    log.info("【出库任务】堆垛机取货成功");
                    stackerTaskOut.setStackerTaskOutPace("取货");
                    stackerTaskOutService.updateStackerTaskOut(stackerTaskOut);
                }
                log.info("【出库任务】堆垛机取货成功");
                /*Boolean stockPositionStatus = checkStockPosition(stackers.get(0), stackerTaskOut.getShelvePlcValue(), stackerTaskOut.getStockWidth(), stackerTaskOut.getStockHeight(), stackerTaskOut.getStackerTaskOutCode());
                if (stockPositionStatus == null || stockPositionStatus) {
                    log.error("【出库任务】判断货位状态失败，stackerTaskOutCode={}", stackerTaskOutCode);
                    break;
                }*/
                // 模拟判断货位状态
                /*try {
                    Thread.sleep(10000);
                } catch (Exception ignored) {
                }
                int max = 100, min = 1;
                int ran2 = (int) (Math.random() * (max - min) + min);
                if (ran2 > 80) {
                    log.error("【出库任务】判断货位状态失败，stackerTaskOutCode={}", stackerTaskOutCode);
                    break;
                }*/
                log.info("【出库任务】判断货位状态成功");
                if (!stackerTaskOut.getStackerTaskOutPace().equals("放货") && !stackerTaskOut.getStackerTaskOutPace().equals("出货")) {
                    if (!pullDownProduct(stackerTaskOut, stackers.get(0), tdPlcUtil)) {
                        log.error("【出库任务】堆垛机放货失败，stackerTaskOutCode={}", stackerTaskOutCode);
                        break;
                    }
                    // 模拟取货过程
                    /*try {
                        Thread.sleep(10000);
                    } catch (Exception ignored) {
                    }
                    max = 100;
                    min = 1;
                    ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【出库任务】堆垛机放货失败，stackerTaskOutCode={}", stackerTaskOutCode);
                        break;
                    }*/
                }
                if (!stackerTaskOut.getStackerTaskOutPace().equals("出货")) {
                    if (!beltDownProduct(stackerTaskOut, hcPlcUtil)) {
                        log.error("【出库任务】堆垛机传送带出货失败，stackerTaskOutCode={}", stackerTaskOutCode);
                        break;
                    }
                    // 模拟出货过程
                    /*try {
                        Thread.sleep(10000);
                    } catch (Exception ignored) {
                    }
                    int max = 100, min = 1;
                    int ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【出库任务】堆垛机出货失败，stackerTaskOutCode={}", stackerTaskOutCode);
                        break;
                    }*/
                }
                log.info("【出库任务】堆垛机放货成功");
                pullOrderBoxDetails.get(0).setBoxDetailStatus("已出库");
                pullOrderBoxDetailService.updateByPrimaryKey(pullOrderBoxDetails.get(0));
                List<PullOrderBoxDetail> pullOrderBoxDetailList = pullOrderBoxDetailService.findByDetailCodeAndStatus(pullOrderBoxDetails.get(0).getPullOrderDetailCode(), "已出库");
                Integer countSum = pullOrderBoxDetailList.stream().mapToInt(PullOrderBoxDetail::getUnintCount).sum();
                pullOrderDetails.get(0).setFinishCount(countSum);
                if (pullOrderDetails.get(0).getFinishCount() >= pullOrderDetails.get(0).getPullOrderCount()) {
                    pullOrderDetails.get(0).setProductPullPace("已完成");
                }
                pullOrderDetailService.updateByPrimaryKey(pullOrderDetails.get(0));
                PullOrderDetailExample pullOrderDetailExample = new PullOrderDetailExample();
                pullOrderDetailExample.or().andPullOrderCodeEqualTo(pullOrderDetails.get(0).getPullOrderCode());
                List<PullOrderDetail> pullOrderDetailList = pullOrderDetailService.selectByExample(pullOrderDetailExample);
                pullOrderDetailList = pullOrderDetailList.stream().filter(e -> e.getProductPullPace() != null && e.getProductPullPace().equals("进行中")).collect(Collectors.toList());
                pullOrders.get(0).setPullOrderStatus("出库中");
                if (pullOrderDetailList.size() == 0) {
                    pullOrders.get(0).setPullOrderStatus("已完成");
                }
                pullOrderService.updateByPrimaryKey(pullOrders.get(0));
                stocks.get(0).setStockStatus("空闲");
                stocks.get(0).setProductCode("");
                stocks.get(0).setProductName("");
                stocks.get(0).setUnitCount(null);
                stocks.get(0).setPushOrderCode("");
                stocks.get(0).setPushOrderDetailCode("");
                stocks.get(0).setPushTime(null);
                stocks.get(0).setBoxDetailCode("");
                stocks.get(0).setBatchNumber("");
                stocks.get(0).setBoxCode("");
                stockService.updateByPrimaryKey(stocks.get(0));
                stackerTaskOut.setStackerTaskOutPace("放货");
                stackerTaskOut.setStackerTaskOutStatus("已完成");
                stackerTaskOutService.updateStackerTaskOut(stackerTaskOut);
            }
            if (stackerTaskOut != null && !stackerTaskOut.getStackerTaskOutStatus().equals("已完成")) {
                stackerTaskOut.setStackerTaskOutStatus("中断");
                stackerTaskOutService.updateStackerTaskOut(stackerTaskOut);
            }
            if (tdPlcUtil != null) {
                tdPlcUtil.disConnect();
            }
            if (hcPlcUtil != null) {
                hcPlcUtil.disConnect();
            }
        } catch (Exception e) {
            log.error("【出库任务】任务发生异常，stackerTaskOutCode={}", stackerTaskOutCode);
            if (tdPlcUtil != null) {
                tdPlcUtil.disConnect();
            }
            if (hcPlcUtil != null) {
                hcPlcUtil.disConnect();
            }
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            StackerTaskOut stackerTaskOut = stackerTaskOutService.findByStackerTaskOutCode(stackerTaskOutCode);
            if (stackerTaskOut != null) {
                stackerTaskOut.setStackerTaskOutStatus("中断");
                stackerTaskOutService.updateStackerTaskOut(stackerTaskOut);
            }
        }
    }

    @Async
    public void moveProduct(String stackerTaskMoveCode) {
        try {
            log.info("【移库任务】stackerTaskMoveCode={}", stackerTaskMoveCode);
            StackerTaskMove stackerTaskMove = stackerTaskMoveService.findByStackerTaskMoveCode(stackerTaskMoveCode);
            List<MoveBoxDetail> moveBoxDetails = new ArrayList<>();
            List<Stacker> stackers = new ArrayList<>();
            List<Stock> oldStocks = new ArrayList<>();
            List<Stock> newStocks = new ArrayList<>();
            if (stackerTaskMove != null) {
                if (stackerTaskMove.getStackerName() != null) {
                    stackers = stackerService.findByStackerName(stackerTaskMove.getStackerName());
                }
                if (stackerTaskMove.getMoveDetailCode() != null) {
                    MoveBoxDetailExample moveBoxDetailExample = new MoveBoxDetailExample();
                    moveBoxDetailExample.or().andMoveDetailCodeEqualTo(stackerTaskMove.getMoveDetailCode());
                    moveBoxDetails = moveBoxDetailService.selectByExample(moveBoxDetailExample);
                }
                if (stackerTaskMove.getOldShelveName() != null && stackerTaskMove.getOldShelveWidth() != null && stackerTaskMove.getOldShelveHeight() != null) {
                    oldStocks = stockService.findByShelveNameAndWidthAndHeight(stackerTaskMove.getOldShelveName(), stackerTaskMove.getOldShelveWidth(), stackerTaskMove.getOldShelveHeight());
                }
                if (stackerTaskMove.getNewShelveName() != null && stackerTaskMove.getNewShelveWidth() != null && stackerTaskMove.getNewShelveHeight() != null) {
                    newStocks = stockService.findByShelveNameAndWidthAndHeight(stackerTaskMove.getNewShelveName(), stackerTaskMove.getNewShelveWidth(), stackerTaskMove.getNewShelveHeight());
                }
            }
            for (int i = 0; i < 1; i++) {
                if (stackerTaskMove == null) {
                    log.error("【移库任务】堆垛机任务不存在，stackerTaskMove={}", stackerTaskMoveCode);
                    break;
                }
                taskLogService.deleteByStackerName(stackerTaskMove.getStackerName());
                if (stackers.size() == 0) {
                    log.error("【移库任务】堆垛机不存在，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "堆垛机不存在");
                    break;
                }
                if (moveBoxDetails.size() == 0) {
                    log.error("【移库任务】移库详情不存在，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "移库详情不存在");
                    break;
                }
                if (oldStocks.size() == 0 || !oldStocks.get(0).getStockStatus().equals("已绑定")) {
                    log.error("【移库任务】货位不存在或未绑定，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "货位不存在或未绑定");
                    break;
                }
                if (newStocks.size() == 0 || !newStocks.get(0).getStockStatus().equals("已绑定")) {
                    log.error("【移库任务】货位不存在或未绑定，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "货位不存在或未绑定");
                    break;
                }
                if (stackers.get(0).getStackerIP() == null || stackers.get(0).getStackerIP().equals("")
                        || stackers.get(0).getStackerPort() == null
                        || stackers.get(0).getStackerPickAddress() == null
                        || stackers.get(0).getStackerPickHeight() == null
                        || stackers.get(0).getStackerPickWidth() == null) {
                    log.error("【移库任务】堆垛机参数缺失，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "堆垛机参数缺失");
                    break;
                }
                if (stackerTaskMove.getOldShelveHeight() == null || stackerTaskMove.getOldShelveWidth() == null
                        || stackerTaskMove.getOldShelvePlcValue() == null || stackerTaskMove.getNewShelveHeight() == null
                        || stackerTaskMove.getNewShelveWidth() == null || stackerTaskMove.getNewShelvePlcValue() == null) {
                    log.error("【移库任务】任务参数缺失，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "任务参数缺失");
                    break;
                }
                taskLogService.log(stackerTaskMoveCode, stackerTaskMove.getStackerName(), "移库中");
                if (!stackerTaskMove.getStackerTaskMovePace().equals("取货") && !stackerTaskMove.getStackerTaskMovePace().equals("放货")) {
                    /*if (!moveGetProduct(stackerTaskMove, stackers.get(0))) {
                        log.error("【出库任务】堆垛机取货失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                        break;
                    }*/
                    // 模拟取货过程
                    try {
                        Thread.sleep(15000);
                    } catch (Exception ignored) {
                    }
                    int max = 100, min = 1;
                    int ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【移库任务】堆垛机取货失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                        break;
                    }
                    stackerTaskMove.setStackerTaskMovePace("取货");
                    stackerTaskMoveService.updateStackerTaskMove(stackerTaskMove);
                }
                log.info("【移库任务】堆垛机取货成功");
                /*Boolean stockPositionStatus = checkStockPosition(stackers.get(0), stackerTaskMove.getOldShelvePlcValue(), stackerTaskMove.getOldShelveWidth(), stackerTaskMove.getOldShelveHeight(), stackerTaskMove.getStackerTaskMoveCode());
                if (stockPositionStatus == null || stockPositionStatus) {
                    log.error("【移库任务】判断货位状态失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    break;
                }*/
                // 模拟判断货位状态
                try {
                    Thread.sleep(10000);
                } catch (Exception ignored) {
                }
                int max = 100, min = 1;
                int ran2 = (int) (Math.random() * (max - min) + min);
                if (ran2 > 80) {
                    log.error("【移库任务】判断货位状态失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    break;
                }
                log.info("【移库任务】判断货位状态成功");
                if (!stackerTaskMove.getStackerTaskMovePace().equals("放货")) {
                    /*if (!moveDownProduct(stackerTaskMove, stackers.get(0))) {
                        log.error("【出库任务】堆垛机放货失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                        break;
                    }*/
                    // 模拟取货过程
                    try {
                        Thread.sleep(15000);
                    } catch (Exception ignored) {
                    }
                    max = 100;
                    min = 1;
                    ran2 = (int) (Math.random() * (max - min) + min);
                    if (ran2 > 80) {
                        log.error("【移库任务】堆垛机放货失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                        break;
                    }
                }
                log.info("【移库任务】堆垛机放货成功");
                /*Boolean stockPositionStatus = checkStockPosition(stackers.get(0), stackerTaskMove.getOldShelvePlcValue(), stackerTaskMove.getOldShelveWidth(), stackerTaskMove.getOldShelveHeight(), stackerTaskMove.getStackerTaskMoveCode());
                if (stockPositionStatus == null || !stockPositionStatus) {
                    log.error("【移库任务】判断货位状态失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    break;
                }*/
                // 模拟判断货位状态
                try {
                    Thread.sleep(10000);
                } catch (Exception ignored) {
                }
                max = 100;
                min = 1;
                ran2 = (int) (Math.random() * (max - min) + min);
                if (ran2 > 80) {
                    log.error("【移库任务】判断货位状态失败，stackerTaskMoveCode={}", stackerTaskMoveCode);
                    break;
                }
                log.info("【移库任务】判断货位状态成功");
                // 更新移库详情， 库位信息
                moveBoxDetails.get(0).setMoveDetailStatus("已移库");
                moveBoxDetailService.updateByPrimaryKey(moveBoxDetails.get(0));
                newStocks.get(0).setPushOrderCode(oldStocks.get(0).getPushOrderCode());
                newStocks.get(0).setPushOrderDetailCode(oldStocks.get(0).getPushOrderDetailCode());
                newStocks.get(0).setProductCode(oldStocks.get(0).getProductCode());
                newStocks.get(0).setProductName(oldStocks.get(0).getProductName());
                newStocks.get(0).setStockStatus("已存放");
                newStocks.get(0).setUnitCount(oldStocks.get(0).getUnitCount());
                oldStocks.get(0).setPushOrderCode("");
                oldStocks.get(0).setPushOrderDetailCode("");
                oldStocks.get(0).setProductCode("");
                oldStocks.get(0).setProductName("");
                oldStocks.get(0).setStockStatus("空闲");
                oldStocks.get(0).setUnitCount(0);
                stockService.updateByPrimaryKey(newStocks.get(0));
                stockService.updateByPrimaryKey(oldStocks.get(0));
                stackerTaskMove.setStackerTaskMovePace("放货");
                stackerTaskMove.setStackerTaskMoveStatus("已完成");
                stackerTaskMoveService.updateStackerTaskMove(stackerTaskMove);
            }
            if (stackerTaskMove != null && !stackerTaskMove.getStackerTaskMoveStatus().equals("已完成")) {
                stackerTaskMove.setStackerTaskMoveStatus("中断");
                stackerTaskMoveService.updateStackerTaskMove(stackerTaskMove);
            }
        } catch (Exception e) {
            log.error("【移库任务】任务发生异常，stackerTaskMoveCode={}", stackerTaskMoveCode);
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            StackerTaskMove stackerTaskMove = stackerTaskMoveService.findByStackerTaskMoveCode(stackerTaskMoveCode);
            if (stackerTaskMove != null) {
                stackerTaskMove.setStackerTaskMoveStatus("中断");
                stackerTaskMoveService.updateStackerTaskMove(stackerTaskMove);
            }
        }
    }

    private Boolean beltDownProduct(StackerTaskOut stackerTaskOut, HCPlcUtil hcPlcUtil) {
        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "开始传送带放货");
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "执行第" + i + "次降气缸任务");
                if (!hcPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "成功连接到PLC");
                if (!hcPlcUtil.writeCoil(50, new Boolean[]{true})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放货层信息到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "判断气缸已降完成");
                isDone = true;
                break;
            }
            if (!isDone) {
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "传送带到位失败");
            }
            return isDone;
        } catch (Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            return false;
        }
    }

    private Boolean beltGetProduct(StackerTaskIn stackerTaskIn, Stacker stacker, TDPlcUtil tdPlcUtil, HCPlcUtil hcPlcUtil) {
        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "开始传送带取货");
        boolean isDone = false;
        try {
            // 传送带气缸降堆垛机到准备位
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次降气缸任务");
                if (!hcPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                    continue;
                }
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                Boolean[] result = hcPlcUtil.readCoil(61, 1);
                if (result == null || result.length != 1) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取PLC气缸状态失败");
                    continue;
                }
                if (result[0]) {
                    if (!hcPlcUtil.writeCoil(62, new Boolean[]{true})) {
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写降气缸信号失败");
                    }
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(14, new long[]{stacker.getStackerPickHeight()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放货层信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(15, new long[]{stacker.getStackerPickWidth()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(13, new long[]{stacker.getStackerPickAddress()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写货架位信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(16, new long[]{2})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.0", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.6", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放启动信号到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "判断气缸已降并发送堆垛机到准备位信号完成");
                isDone = true;
                break;
            }
            // 传送带走
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 5; i++) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次写传送带入库信号");
                    if (!hcPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                    if (!hcPlcUtil.writeCoil(60, new Boolean[]{true})) {
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写传送带入库信号失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写传送带入库信号成功");
                    isDone = true;
                    break;
                }
            }
            // 等待到位信号
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次等待传送带到位信号");
                    if (!hcPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                    Boolean[] result = hcPlcUtil.readCoil(61, 1);
                    if (result == null || result.length != 1) {
                        i += 5;
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取传送带到位信号失败");
                        continue;
                    }
                    if (!result[0]) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    Integer[] result1 = tdPlcUtil.readStorageWord(34, 1);
                    if (result1 == null) {
                        i += 5;
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取PLC到准备位状态失败");
                        continue;
                    }
                    if (result1[0] != 1) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "传送带到位堆垛机到准备位成功");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "传送带到位堆垛机到准备位失败");
            }
            return isDone;
        } catch (Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            return false;
        }
    }

    private Boolean pushGetProduct(StackerTaskIn stackerTaskIn, Stacker stacker, TDPlcUtil tdPlcUtil) {
        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "开始取货");
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次取货任务");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                if (!tdPlcUtil.writeStorageDWord(14, new long[]{stacker.getStackerPickHeight()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放货层信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(15, new long[]{stacker.getStackerPickWidth()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(13, new long[]{stacker.getStackerPickAddress()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写货架位信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(16, new long[]{1})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.0", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.6", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放启动信号到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货动作信息到PLC成功");
                isDone = true;
                break;
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次等待取货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                    Integer[] result = tdPlcUtil.readStorageWord(34, 1);
                    if (result == null) {
                        i += 5;
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取PLC取货状态失败");
                        continue;
                    }
                    if (result[0] != 1) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取PLC取货状态成功");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "堆垛机取货失败");
            }
            return isDone;
        } catch (Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            return false;
        }
    }

    private Boolean pushDownProduct(StackerTaskIn stackerTaskIn, TDPlcUtil tdPlcUtil, HCPlcUtil hcPlcUtil) {
        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "开始放货");
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次放货任务");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                if (!tdPlcUtil.writeStorageDWord(14, new long[]{stackerTaskIn.getStockHeight()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放货层信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(15, new long[]{stackerTaskIn.getStockWidth()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(13, new long[]{stackerTaskIn.getShelvePlcValue()})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写货架位信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(16, new long[]{3})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.0", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放货列信息到PLC失败");
                    continue;
                }
                if (!hcPlcUtil.writeCoil(62, new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写降气缸信号到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.6", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写放启动信号到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "写取货动作信息到PLC成功");
                isDone = true;
                break;
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "执行第" + i + "次等待放货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "成功连接到PLC");
                    Integer[] result = tdPlcUtil.readStorageWord(34, 1);
                    if (result == null) {
                        i += 5;
                        taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取PLC放货状态失败");
                        continue;
                    }
                    if (result[0] != 1) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "读取PLC放货状态成功");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskIn.getStackerTaskInCode(), stackerTaskIn.getStackerName(), "堆垛机放货失败");
            }
            return isDone;
        } catch (Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            return false;
        }
    }

    private Boolean pullGetProduct(StackerTaskOut stackerTaskOut, Stacker stacker, TDPlcUtil tdPlcUtil) {
        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "开始取货");
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "执行第" + i + "次取货任务");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "成功连接到PLC");
                if (!tdPlcUtil.writeStorageDWord(14, new long[]{stackerTaskOut.getStockHeight()})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放货层信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(15, new long[]{stackerTaskOut.getStockWidth()})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写取货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(13, new long[]{stackerTaskOut.getShelvePlcValue()})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写货架位信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(16, new long[]{1})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写取货信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.0", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.6", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放启动信号到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写取货动作信息到PLC成功");
                isDone = true;
                break;
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "执行第" + i + "次等待取货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "成功连接到PLC");
                    Integer[] result = tdPlcUtil.readStorageWord(34, 1);
                    if (result == null) {
                        i += 5;
                        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "读取PLC取货状态失败");
                        continue;
                    }
                    if (result[0] != 1) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "读取PLC取货状态成功");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "堆垛机取货失败");
            }
            return isDone;
        } catch (Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            return false;
        }

    }

    private Boolean pullDownProduct(StackerTaskOut stackerTaskOut, Stacker stacker, TDPlcUtil tdPlcUtil) {
        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "开始放货");
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "执行第" + i + "次放货任务");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "成功连接到PLC");
                if (!tdPlcUtil.writeStorageDWord(14, new long[]{1})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放货层信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(15, new long[]{105})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写取货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(13, new long[]{20})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写货架位信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeStorageDWord(16, new long[]{3})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写取货信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.0", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放货列信息到PLC失败");
                    continue;
                }
                if (!tdPlcUtil.writeBitMX("0.6", new Boolean[]{true})) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写放启动信号到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "写取货动作信息到PLC成功");
                isDone = true;
                break;
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "执行第" + i + "次等待放货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "成功连接到PLC");
                    Integer[] result = tdPlcUtil.readStorageWord(34, 1);
                    if (result == null) {
                        i += 5;
                        taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "读取PLC取货状态失败");
                        continue;
                    }
                    if (result[0] != 1) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "读取PLC放货状态成功");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskOut.getStackerTaskOutCode(), stackerTaskOut.getStackerName(), "堆垛机放货失败");
            }
            return isDone;
        } catch (Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(stringWriter);
            e.printStackTrace(writer);
            StringBuffer buffer = stringWriter.getBuffer();
            log.error(buffer.toString());
            return false;
        }
    }

    private Boolean moveGetProduct(StackerTaskMove stackerTaskMove, Stacker stacker) {
        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "开始取货");
        TDPlcUtil tdPlcUtil = new TDPlcUtil(stacker.getStackerIP(), stacker.getStackerPort());
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "执行第" + i + "次取货任务");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "成功连接到PLC");
                if (!tdPlcUtil.writeStorageDInt(200, new int[]{stackerTaskMove.getOldShelveWidth(), stackerTaskMove.getOldShelveHeight(), stackerTaskMove.getOldShelvePlcValue(), 1})) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写取货位信息到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写取货位信息到PLC成功");
                if (!tdPlcUtil.writeBitQX("100.0", new Boolean[]{true, false, false})) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写取货动作信息到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写取货动作信息到PLC成功");
                isDone = true;
                break;
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "执行第" + i + "次等待取货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "成功连接到PLC");
                    Boolean[] result = tdPlcUtil.readBitQX("100.1", 1);
                    if (result == null) {
                        i += 5;
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "读取PLC取货状态失败");
                        continue;
                    }
                    if (!result[0]) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "读取PLC取货状态成功");
                    isDone = true;
                    break;
                }
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 5; i++) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "执行第" + i + "次重置取货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "成功连接到PLC");
                    if (!tdPlcUtil.writeBitQX("100.1", new Boolean[]{false})) {
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "重置PLC状态失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "堆垛机取货完成");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "堆垛机取货失败");
            }
            tdPlcUtil.disConnect();
            return isDone;
        } catch (Exception e) {
            tdPlcUtil.disConnect();
            return false;
        }
    }

    private Boolean moveDownProduct(StackerTaskMove stackerTaskMove, Stacker stacker) {
        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "开始放货");
        TDPlcUtil tdPlcUtil = new TDPlcUtil(stacker.getStackerIP(), stacker.getStackerPort());
        boolean isDone = false;
        try {
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "执行第" + i + "次放货任务");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "成功连接到PLC");
                if (!tdPlcUtil.writeStorageDInt(200, new int[]{stackerTaskMove.getNewShelveWidth(), stackerTaskMove.getNewShelveHeight(), stackerTaskMove.getNewShelvePlcValue(), 0})) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写放货位信息到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写放货位信息到PLC成功");
                if (!tdPlcUtil.writeBitQX("100.0", new Boolean[]{true, false, false})) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写放货动作信息到PLC失败");
                    continue;
                }
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "写取货动作信息到PLC成功");
                isDone = true;
                break;
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 30; i++) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "执行第" + i + "次等待放货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "成功连接到PLC");
                    Boolean[] result = tdPlcUtil.readBitQX("100.2", 1);
                    if (result == null) {
                        i += 5;
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "读取PLC放货状态失败");
                        continue;
                    }
                    if (!result[0]) {
                        try {
                            Thread.sleep(2000);
                        } catch (Exception ignored) {
                        }
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "读取PLC放货状态成功");
                    isDone = true;
                    break;
                }
            }
            if (isDone) {
                isDone = false;
                for (int i = 1; i <= 5; i++) {
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "执行第" + i + "次重置放货状态");
                    if (!tdPlcUtil.isConnect()) {
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "PLC连接失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "成功连接到PLC");
                    if (!tdPlcUtil.writeBitQX("100.2", new Boolean[]{false})) {
                        taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "重置PLC放货状态失败");
                        continue;
                    }
                    taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "堆垛机放货完成");
                    isDone = true;
                    break;
                }
            }
            if (!isDone) {
                taskLogService.log(stackerTaskMove.getStackerTaskMoveCode(), stackerTaskMove.getStackerName(), "堆垛机放货失败");
            }
            tdPlcUtil.disConnect();
            return isDone;
        } catch (Exception e) {
            tdPlcUtil.disConnect();
            return false;
        }
    }

    private Boolean checkStockPosition(Stacker stacker, Integer shelvePlcValue, Integer shelveWidth, Integer shelveHeight, String stackerTaskCode) {
        taskLogService.log(stackerTaskCode, stacker.getStackerName(), "开始检查指定位置货物状态");
        TDPlcUtil tdPlcUtil = new TDPlcUtil(stacker.getStackerIP(), stacker.getStackerPort());
        boolean isDone = false;
        Boolean[] positionStatus = null;
        for (int i = 1; i <= 5; i++) {
            taskLogService.log(stackerTaskCode, stacker.getStackerName(), "执行第" + i + "次运行堆垛机到指定位置");
            if (!tdPlcUtil.isConnect()) {
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "PLC连接失败");
                continue;
            }
            taskLogService.log(stackerTaskCode, stacker.getStackerName(), "成功连接到PLC");
            Integer[] position = tdPlcUtil.readStorageDInt(210, 2);
            if (position == null || position.length != 2) {
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "读取堆垛机位置信息失败");
                continue;
            }
            if (position[0].equals(shelveWidth) && position[1].equals(shelveHeight)) {
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "运行堆垛机到指定位置成功");
                isDone = true;
                break;
            }
            if (!tdPlcUtil.writeStorageDInt(200, new int[]{shelveWidth, shelveHeight, shelvePlcValue, 2})) {
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "写位置信息到PLC失败");
                continue;
            }
            taskLogService.log(stackerTaskCode, stacker.getStackerName(), "写位置信息到PLC成功");
            if (!tdPlcUtil.writeBitQX("100.0", new Boolean[]{true, false, false})) {
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "写动作信息到PLC失败");
                continue;
            }
            taskLogService.log(stackerTaskCode, stacker.getStackerName(), "写动作信息到PLC成功");
            isDone = true;
            break;
        }
        if (isDone) {
            isDone = false;
            for (int i = 1; i <= 5; i++) {
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "执行第" + i + "次读取货位存放状态");
                if (!tdPlcUtil.isConnect()) {
                    taskLogService.log(stackerTaskCode, stacker.getStackerName(), "PLC连接失败");
                    continue;
                }
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "成功连接到PLC");
                positionStatus = tdPlcUtil.readBitQX("101.0", 1);
                if (positionStatus == null || positionStatus.length != 1) {
                    taskLogService.log(stackerTaskCode, stacker.getStackerName(), "读取货位存放状态失败");
                    continue;
                }
                taskLogService.log(stackerTaskCode, stacker.getStackerName(), "读取货位存放状态成功");
                isDone = true;
                break;
            }
        }
        tdPlcUtil.disConnect();
        if (!isDone) {
            return null;
        }
        return positionStatus[0] != null && positionStatus[0];
    }
}
